<template>
    <n-tooltip>
        <template #trigger>
            <n-button @click="pickLocation">
                <n-icon>
                    <i class="fa fa-crosshairs" />
                </n-icon>
            </n-button>
        </template>
        定位
    </n-tooltip>

    <n-modal
        v-model:show="showPicker"
        preset="card"
        title="选择位置"
        style="width: 650px">
        <div class="cs-picker" ref="pickerRef" />
        <template #footer>
            <n-space justify="flex-end">
                <n-button @click="() => (showPicker = false)">保存</n-button>
            </n-space>
        </template>
    </n-modal>
</template>

<script setup lang="ts">
import { nextTick, ref, watch, toRefs, PropType } from 'vue'
import {
    Viewer,
    Math as CsMath,
    HorizontalOrigin,
    ScreenSpaceEventHandler,
    VerticalOrigin,
    Cartesian2,
    Cartographic,
    ScreenSpaceEventType,
    Ion,
    PinBuilder,
    Cartesian3,
    Color,
    LabelStyle,
    TileMapServiceImageryProvider,
    buildModuleUrl,
} from 'cesium'
import { NSpace, NModal, NButton, NIcon, NTooltip } from 'naive-ui'
import iconList from '@/common/IconList'
import useDiscMsg from '@/composable/useDiscMsg'
import lodash from 'lodash'

const props = defineProps({
    loc: {
        required: true,
        type: Object as PropType<number[]>,
        default: () => [0, 0, 0],
    },
})

const { loc } = toRefs(props)

const emits = defineEmits(['update:loc'])

Ion.defaultAccessToken =
    // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0NjBlYzRiYS0wMDRhLTRjZWYtODJhOS1jZTk5ZmI4ZDg5ZTIiLCJpZCI6ODI1MCwic2NvcGVzIjpbImFzciIsImdjIl0sImlhdCI6MTU1MTU3MDU1Mn0.yfJ_i4EPiunFj_qUftuv1ksx4pUNgnPC16vQCBGrM08'
    'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJhZTJkMzA0NS1mZjg2LTRkZjUtYjFjMi00ZWViOWVhNjdkZTUiLCJpZCI6NzU4MzEsImlhdCI6MTYzODkyOTMxMH0.G8NRwYdB5stq4MHuGtPOuRAEcrGxxkNNJJEtELCaRWs'
const pickerRef = ref(null)

const showPicker = ref(false)
const pickLocation = () => {
    showPicker.value = true
}

let viewer
let pinBuilder = new PinBuilder()
const { message } = useDiscMsg()

const pin_id = 'pin_mark'

const buildMarker = (loc) => {
    if (loc.length < 3) return
    viewer.entities.removeById(pin_id)

    const groceryPin = Promise.resolve(
        pinBuilder.fromUrl(
            // entity.icon,
            iconList.Crosshair,
            Color.ROYALBLUE,
            48,
        ),
    )
        .then((canvas) => {
            viewer.entities.add({
                id: pin_id,
                position: Cartesian3.fromDegrees(loc[0], loc[1], loc[2] || 0),
                billboard: {
                    image: canvas.toDataURL(),
                    verticalOrigin: VerticalOrigin.BOTTOM,
                    color: Color.WHITE,
                    scale: 0.83,
                },
                label: {
                    //填充色
                    fillColor: Color.WHITE,
                    //字体
                    font: 'bold 8pt Segoe UI Semibold',
                    // // 水平原点
                    horizontalOrigin: HorizontalOrigin.CENTER,
                    text: `经度：${loc[0]},纬度${loc[1]}`,
                    outlineColor: Color.BLACK,
                    outlineWidth: 3,
                    pixelOffset: new Cartesian2(0, -65),
                    style: LabelStyle.FILL_AND_OUTLINE,
                    verticalOrigin: VerticalOrigin.TOP,
                    eyeOffset: new Cartesian3(0, 0, -100000),
                },
            })
        })
        .catch((e) => {
            message.warning('图标加载错误，请重新点击')
        })
}

watch(showPicker, () => {
    if (showPicker.value) {
        nextTick(async () => {
            viewer = new Viewer(pickerRef.value, {
                geocoder: false,
                selectionIndicator: false,
                homeButton: false,
                sceneModePicker: false,
                navigationHelpButton: false,
                fullscreenButton: false,
                navigationInstructionsInitiallyVisible: false,
                timeline: false,
                baseLayerPicker: false,
                animation: false,
                imageryProvider: new TileMapServiceImageryProvider({
                    url: buildModuleUrl('Assets/Textures/NaturalEarthII'),
                }),
            })

            buildMarker(loc.value)

            viewer.camera.flyTo({
                destination: Cartesian3.fromDegrees(
                    loc.value[0] || 0,
                    loc.value[1] || 0,
                    10000000,
                ),
                duration: 0.8,
            })

            const scene = viewer.scene
            if (!scene.pickPositionSupported) {
                window.alert('This browser does not support pickPosition.')
            }
            const entity = viewer.entities.add({
                label: {
                    show: false,
                    showBackground: true,
                    font: '14px monospace',
                    horizontalOrigin: HorizontalOrigin.LEFT,
                    verticalOrigin: VerticalOrigin.TOP,
                    pixelOffset: new Cartesian2(15, 0),
                },
            })

            let handler
            handler = new ScreenSpaceEventHandler(scene.canvas)
            handler.setInputAction(function (movement) {
                const cartesian = viewer.camera.pickEllipsoid(
                    movement.endPosition,
                    scene.globe.ellipsoid,
                )
                if (cartesian) {
                    const cartographic = Cartographic.fromCartesian(cartesian)
                    const longitudeString = CsMath.toDegrees(
                        cartographic.longitude,
                    ).toFixed(2)
                    const latitudeString = CsMath.toDegrees(
                        cartographic.latitude,
                    ).toFixed(2)

                    entity.position = cartesian
                    entity.label.show = true
                    entity.label.text =
                        `Lon: ${`   ${longitudeString}`.slice(-7)}\u00B0` +
                        `\nLat: ${`   ${latitudeString}`.slice(
                            -7,
                        )}\u00B0 双击选择坐标`
                } else {
                    entity.label.show = false
                }
            }, ScreenSpaceEventType.MOUSE_MOVE)
            handler.setInputAction((movement) => {
                viewer.entities.removeById('pin_marker')

                const cartesian = viewer.camera.pickEllipsoid(
                    movement.position,
                    scene.globe.ellipsoid,
                )
                if (cartesian) {
                    const cartographic = Cartographic.fromCartesian(cartesian)
                    const longitudeString = CsMath.toDegrees(
                        cartographic.longitude,
                    )
                    const latitudeString = CsMath.toDegrees(
                        cartographic.latitude,
                    )

                    let lng = lodash.floor(longitudeString, 3)
                    let lat = lodash.floor(latitudeString, 3)

                    const pin_entity = {
                        id: 'pin_marker',
                        lng: lng,
                        lat: lat,
                        // lng:cartographic.longitude,
                        // lat:cartographic.latitude,
                    }

                    emits('update:loc', [lng, lat, 0])
                    buildMarker([lng, lat, 0])
                }
            }, ScreenSpaceEventType.LEFT_DOUBLE_CLICK)
        })
    } else {
        if (!!viewer) {
            viewer.destroy()
        }
    }
})
</script>

<style lang="scss" scoped>
.cs-picker {
    height: 600px;
    width: 600px;
}
</style>
<style>
.cesium-viewer-bottom {
    display: none;
    //top: 200px;
}

.cesium-widget-credits {
    display: none;
}

.cesium-viewer-toolbar {
    top: 68px;
    left: 435px;
}

.cesium-baseLayerPicker-dropDown {
    z-index: 25;
    top: -4px;
    border-radius: 2px;
}
</style>
